﻿namespace NMortgage.UI.ViewModels
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;

    using Caliburn.Micro;

    using NMortgage.UI.Events;
    using NMortgage.UI.Model;

    public sealed class InterestParameterViewModel : Screen
    {
        #region Fields

        private readonly IEventAggregator eventAggregator;

        private DistributionType rateType;
        private Dictionary<DistributionType, ARateViewModel> rateViewModels;

        #endregion Fields

        #region Constructors

        public InterestParameterViewModel(IEventAggregator eventAggregator)
            : this(eventAggregator, new InterestParameter())
        {
        }

        public InterestParameterViewModel(IEventAggregator eventAggregator, IInterestRate parameter)
        {
            this.eventAggregator = eventAggregator;
            Rate = parameter;
            RateDistributionType = parameter.DistributionType;
            rateViewModels = InitRates();
        }

        #endregion Constructors

        #region Properties

        public Array AvailableTypes
        {
            get { return Enum.GetValues(typeof(DistributionType)); }
        }

        public bool IsValid
        {
            get
            {
                IValidatable rate = this.Rate as IValidatable;
                return (rate != null) ? rate.IsValid : true;
            }
        }

        public IInterestRate Rate
        {
            get;
            set;
        }

        public DistributionType RateDistributionType
        {
            get
            {
                return rateType;
            }
            set
            {
                if (rateType != value)
                {
                    rateType = value;
                    Rate.DistributionType = value;
                    NotifyOfPropertyChange(() => RateDistributionType);
                    NotifyOfPropertyChange(() => Rate);
                    NotifyOfPropertyChange(() => RateView);
                }
            }
        }

        public ARateViewModel RateView
        {
            get
            {
                rateViewModels[Rate.DistributionType].Rate = Rate.Distribution;
                return rateViewModels[Rate.DistributionType];
            }
        }

        #endregion Properties

        #region Methods

        public void Cancel()
        {
            eventAggregator.Publish(new CancelEvent(this));
        }

        public void Finish()
        {
            if (IsValid)
            {
                eventAggregator.Publish(new ProfileItemAdded(Rate));
            }
        }

        private Dictionary<DistributionType, ARateViewModel> InitRates()
        {
            Dictionary<DistributionType, ARateViewModel> d = new Dictionary<DistributionType, ARateViewModel>();
            d.Add(Model.DistributionType.FixedRate, new FixedRateViewModel());
            d.Add(Model.DistributionType.BetaDistribution, new BetaRateViewModel());
            d.Add(Model.DistributionType.NormalDistribution, new NormalRateViewModel());
            d.Add(Model.DistributionType.UniformDistribution, new UniformRateViewModel());

            return d;
        }

        #endregion Methods
    }
}